昨天,我改好的草稿準備好要送回 GitHub 了。接下來的問題是:雲端的 Macaron 要怎麼知道「有新東西來了」?
GitHub 有一個功能叫 Webhook,每當有新的東西送進來,它就會主動發一則通知給指定的地方,說「嘿,這邊有更新」。我自己的助理系統也是這樣運作的,只要我把新版本送上 GitHub,雲端那台主機就會收到通知,自己去更新。
我很喜歡把它想成門鈴。有人按了,屋裡的人就知道門外有人,但門鈴響了,只能說明門外有人,他是誰還沒確認,更不能因為一聲門鈴,就直接讓他把東西搬進屋裡。
所以 Day 18 做的,是聽到門鈴之後,Macaron 要怎麼應門。
每一則通知進來,Macaron 第一件事是確認它真的是 GitHub 發的。GitHub 會在通知上附一個簽名,這個簽名只有手上握著同一把鑰匙的兩邊才算得出來,Macaron 用自己的鑰匙重新算一次,對得上才相信。
接著再看內容:通知不能太大,上限是 256 KB,格式必須完整正確,說的必須是 Macaron 自己的專案、主要的那條版本線,而且是一次一般的送出。如果這次的變動是強制蓋掉過去的歷史、新建或刪掉一條版本線,或者前後兩個版本根本一樣,就先停下來不處理。
就算驗證失敗,Macaron 回的錯誤訊息裡也不會出現那把鑰匙,或把整則通知原封不動印出來,錯誤處理本身,也不能變成洩密的地方。
GitHub 的通知裡,其實會附一份「這次改了哪些檔案」的清單。Macaron 刻意不用這份清單。
它只記下最少的幾件事:哪個專案、哪條版本線、改之前是哪一版、改之後是哪一版,以及這則通知的編號。之後真正去處理的時候,Macaron 會自己去看實際改了什麼,確認只動到占卜草稿的那個資料夾,再用前幾天那一套規則重新檢查一次。
門鈴可以告訴屋裡「可以開始查了」,但不能替屋裡的人說「我已經幫你查過了」。
網路的世界裡,同一則通知常常會被送來不只一次。所以 Macaron 會用通知的編號來辨認,同一則通知第二次來、而且內容完全一樣,它就回一句「收過了」,不會再排一次工作;同一個編號卻帶著不一樣的內容,那就不是重送,是有問題,直接拒絕。
這裡有一個一開始沒想到的洞。最早的做法是分兩步:先登記「這則收到了」,再把工作存起來。後來發現,如果第一步成功、第二步失敗,登記上寫著收到了,工作卻沒有存下來,之後 GitHub 重送,Macaron 一看「這則收過了」就跳過,這個工作就永遠不會被處理,也沒有人會發現。
所以現在登記和工作是綁在一起存的,要嘛一起成功,要嘛一起不算數,失敗了就什麼都沒留下,下一次重送還是可以正常處理。
今天 Macaron 還沒有真的在網路上開一扇門,GitHub 那邊也還沒設定要通知它,測試用的是假的鑰匙和假的通知。
門鈴有了,但門鈴偶爾會漏響。如果我再安排一個人,每隔一段時間就去門口巡一次,那門鈴和巡邏的人同時發現同一件事的時候,要聽誰的?